//
//  AMHttpMgr.m
//  WeiDu_1_0
//
//  Created by foguo-mac-1 on 01/07/16.
//  Copyright (c) 2016 WeiDu Energy Tech. All rights reserved.
//

#import "HOHttpMgr.h"
#import "HOBaseRequestEntity.h"
#import "HOBaseResponseEntity.h"
#import "HOResponseFactory.h"
#import "HOResponseFactory.h"
#import "Logger.h"
#import "HOConstants.h"
#import "Reachability.h"

@implementation HOHttpMgr
@synthesize delegate;

- (instancetype)init
{
    if(self = [super init])
    {
        threadCount = 5;
        requestList = [[NSMutableArray alloc]init];
        httpRequestDic = [[NSMutableDictionary alloc] init];
        requestingList = [[NSMutableArray alloc]init];
        
    }
    return self;
}

#pragma mark
#pragma mark Reqeust handle --

- (void)checkNextReqeust
{
    if(httpRequestDic.count >= threadCount)
    {
        return;
    }
    HOBaseRequestEntity *nextRequest = [self getNextRequest];
    if(nextRequest == nil)
        return;
    [self doRequest:nextRequest];
    [requestingList addObject:nextRequest];
//    LogInf(@"[nextRequest retainCount]:%d", [nextRequest retainCount]);
    [requestList removeObject:nextRequest];
}

- (void)doRequest:(HOBaseRequestEntity *)request
{
    HOHttpRequest *httpRequest = [[HOHttpRequest alloc] init];
    [httpRequestDic setObject:httpRequest forKey:[NSNumber numberWithInt:request.sequence]];
    httpRequest.delegate = self;
	request.httpRequest = httpRequest;
    [httpRequest doRequest:request];
    [httpRequest release];
}

- (HOBaseRequestEntity *)getNextRequest
{
    if([requestList count] == 0)
        return nil;
//    LogInf(@"requestList:%@", requestList);
    return [requestList firstObject];
}

- (void)destroyRequest:(HOBaseRequestEntity *)request
{
    @synchronized(self)
    {
        
//        LogInf(@"doRequest request.sequencen:%d, request:%@", request.sequence, request);
        [self cancel:request];
        
        [httpRequestDic removeObjectForKey:[NSNumber numberWithInt:request.sequence]];
        [requestList removeObject:request];
        [requestingList removeObject:request];
    }
}

#pragma mark
#pragma mark AMHttpRequestDelegate implement methods --

- (void)didReceiveResponse:(HOBaseResponseEntity *)response
{
	
    [self.delegate didReceiveResponse:response];
	if(response.baseRequest.status != HO_REQUEST_STATUS_UNDO && response.baseRequest.status != HO_REQUEST_STATUS_DOING)
	{
		[self destroyRequest:response.baseRequest];
		[self checkNextReqeust];
	}
}
- (BOOL)isNetworkAvailable
{
    CFNetDiagnosticRef dReference = CFNetDiagnosticCreateWithURL (NULL, (__bridge CFURLRef)[NSURL URLWithString:@"wwww.baidu.com"]);
    
//    CFNetDiagnosticStatus status;
//    status =
 CFNetDiagnosticCopyNetworkStatusPassively (dReference, NULL);
    
    CFRelease (dReference);
      return YES;
//    if ( status == kCFNetDiagnosticConnectionUp )
//    {
//        LogInf (@"Connection is Available");
//        return YES;
//    }
//    else
//    {
//        LogInf (@"Connection is down");
//        return NO;
//    }
}
#pragma mark
#pragma mark HOHTTPMgrDelegate implement methods --

- (void)sendRequest:(HOBaseRequestEntity *)request
{
    
    
    HOBaseResponseEntity *response = [[[HOResponseFactory sharedInstance]
                                           getResponseWithRequest:request] retain];
    if(![self isNetworkAvailable])
    {
        request.status =  HO_REQUEST_STATUS_FAILED;
		[response setErrorCode:ERROR_CODE_NETWORK_DOWN];
    }
    else
    {
        request.status =  HO_REQUEST_STATUS_DOING;
    }
    request.requestTimes = 0;
    [self.delegate didReceiveResponse:response];
    [response release];
    
    if([self isNetworkAvailable])
    {
        @synchronized(self)
        {
            [requestList addObject:request];
            [self checkNextReqeust];
        }
    }

}

- (void)cancel:(HOBaseRequestEntity *)request
{
//    LogInf(@"cancel request:%@ sequence:%d", request, request.sequence);
    HOHttpRequest *httpRequest = [httpRequestDic objectForKey:[NSNumber numberWithInt:request.sequence]];
//    LogInf(@"httpRequest:%@", httpRequest);
    if(httpRequest)
    {
        [httpRequest cancelRequest];
    }
    httpRequest.delegate = nil;
//    [self cleanup];
}

- (void)cancelAllRequest
{
	for(int i = 0; i < [requestingList count]; i ++)
	{
		HOBaseRequestEntity *request = [requestingList objectAtIndex:i];
		[self cancel:request];
	}
    for(int i = 0; i < [requestList count]; i ++)
    {
        HOBaseRequestEntity *request = [requestList objectAtIndex:i];
        [self cancel:request];
    }
    [self cleanup];
    
}

- (void)cleanup
{
    @synchronized(self)
    {
        [requestList removeAllObjects];
        [httpRequestDic removeAllObjects];
        [requestingList removeAllObjects];
    }
}

#pragma mark
- (void)dealloc
{
    [self cleanup];
    [requestList release];
    requestList = nil;
    [requestingList release];
    requestingList = nil;
    
    [httpRequestDic release];
    httpRequestDic = nil;
    
    [super dealloc];
}

@end
